package com.nanyang.tms.manager.forecast.handler;

import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.nanyang.common.core.annotation.SystemLog;
import com.nanyang.common.core.annotation.SystemMessage;
import com.nanyang.common.core.dict.CommonEnum;
import com.nanyang.common.core.domain.ApiResult;
import com.nanyang.common.core.flow.context.TransHandlerContext;
import com.nanyang.common.core.flow.handler.AbstractTransHandler;
import com.nanyang.common.tool.utils.convert.BeanUtils;
import com.nanyang.common.tool.utils.uuid.GlobalIdGeneratorUtil;
import com.nanyang.sys.api.dto.response.country.CityResponse;
import com.nanyang.sys.api.dto.response.country.CountryResponse;
import com.nanyang.sys.api.dto.response.dict.DictionaryResponse;
import com.nanyang.sys.api.service.country.CountryRpcService;
import com.nanyang.sys.api.service.dict.DictionaryRpcService;
import com.nanyang.tms.common.contstant.TmsSerializeConstant;
import com.nanyang.tms.common.dict.TmsExceptionEnum;
import com.nanyang.tms.common.exception.TmsManagerException;
import com.nanyang.tms.common.util.TmsExceptionUtil;
import com.nanyang.tms.dao.company.CompanyDao;
import com.nanyang.tms.dao.forecast.ForecastDao;
import com.nanyang.tms.dao.forecast.ForecastDeclareDao;
import com.nanyang.tms.dao.forecast.ForecastReceiverDao;
import com.nanyang.tms.dao.forecast.ForecastSenderDao;
import com.nanyang.tms.dao.forecast.ForecastVolumeDao;
import com.nanyang.tms.dao.saleproduct.SaleProductDao;
import com.nanyang.tms.domain.company.CompanyVO;
import com.nanyang.tms.domain.forecast.ForecastDO;
import com.nanyang.tms.domain.forecast.ForecastDeclareDO;
import com.nanyang.tms.domain.forecast.ForecastQuery;
import com.nanyang.tms.domain.forecast.ForecastReceiverDO;
import com.nanyang.tms.domain.forecast.ForecastSenderDO;
import com.nanyang.tms.domain.forecast.ForecastVolumeDO;
import com.nanyang.tms.domain.forecast.context.CalculateFreightContext;
import com.nanyang.tms.domain.forecast.context.CalculateWeightContext;
import com.nanyang.tms.domain.forecast.context.CalculateWeightVolumeContext;
import com.nanyang.tms.domain.forecast.context.saveforecast.SaveForecastContext;
import com.nanyang.tms.domain.forecast.context.saveforecast.SaveForecastDeclareContext;
import com.nanyang.tms.domain.saleproduct.SaleProductVO;
@Component
public class SaveForecastHandler extends AbstractTransHandler{
	private static final String PLATFORM_DIC_TYPE_CODE="PLATFORM_TYPE_CODE";
	@Autowired
	private ForecastDao forecastDao;
	@Autowired
	private ForecastReceiverDao forecastReceiverDao;
	@Autowired
	private ForecastSenderDao forecastSenderDao;
	@Autowired
	private ForecastVolumeDao  forecastVolumeDao;
	@Autowired
	private ForecastDeclareDao forecastDeclareDao;
	@Autowired
	private GlobalIdGeneratorUtil globalIdGeneratorUtil;
	@Autowired
	private CompanyDao companyDao;
	@Autowired
	private SaleProductDao saleProductDao;
    @Reference(version = "1.0.0", timeout = 10000, check = false)
	private CountryRpcService  countryRpcService;
    @Reference(version = "1.0.0", timeout = 10000, check = false)
	private DictionaryRpcService  dictionaryRpcService;
	@Override
	public boolean isAsync() {
		// TODO Auto-generated method stub
		return false;
	}
	@SystemMessage(messageType=SystemMessage.MessageType.SERVICE,template="forecastAddMessage")
    @SystemLog(module =SystemLog.Module.FORCECAST,template="forecastAddLog")
	@Override
	public boolean handle(TransHandlerContext context) {
		SaveForecastContext saveForecastContext=(SaveForecastContext)context.getInnerContext(SaveForecastContext.class);
		CalculateFreightContext calculateFreightContext=(CalculateFreightContext)context.getInnerContext(CalculateFreightContext.class);
		CalculateWeightContext calculateWeightContext=(CalculateWeightContext)context.getInnerContext(CalculateWeightContext.class);
		try {
			validateCustomNo(saveForecastContext, calculateFreightContext);
			String nextSeq = TmsSerializeConstant.FORCAST_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.FORCAST_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
			//bulid  Forecast并插入
			ForecastDO forecastDO = buildForcast(nextSeq, saveForecastContext,
					calculateFreightContext, calculateWeightContext);
			forecastDao.insert(forecastDO);
			//bulid  ForecastReceiver并插入
			ForecastReceiverDO  forecastReceiverDO=new ForecastReceiverDO();
			setForecastReceiverDO(nextSeq,forecastReceiverDO,saveForecastContext,calculateFreightContext,calculateWeightContext);
			forecastReceiverDao.insert(forecastReceiverDO);
			//bulid ForecastSender并插入
			ForecastSenderDO forecastSenderDO = new ForecastSenderDO();
			setForecastSenderDO(nextSeq, forecastSenderDO, saveForecastContext, calculateFreightContext);
			forecastSenderDao.insert(forecastSenderDO);
			
			//bulid ForecastDeclare并插入
			saveForecastContext.getSaveForecastDeclareContexts().forEach(x ->{
				ForecastDeclareDO  forecastDeclareDO =new ForecastDeclareDO();
				setForecastDeclareDO(nextSeq, forecastDeclareDO, x, calculateFreightContext);
				forecastDeclareDO.setIp(saveForecastContext.getIp());
				forecastDeclareDO.setGmtCreatePin(saveForecastContext.getPin());
				forecastDeclareDO.setGmtModifiedPin(saveForecastContext.getPin());
				forecastDeclareDao.insert(forecastDeclareDO);
			});
			//bulid ForecastVolume并插入
			calculateWeightContext.getCalculateWeightVolumeContexts().forEach( x -> {
				ForecastVolumeDO forecastVolumeDO=new ForecastVolumeDO();
				setForecastVolumeDO(nextSeq, forecastVolumeDO, x, calculateFreightContext);
				forecastVolumeDO.setIp(saveForecastContext.getIp());
				forecastVolumeDO.setGmtCreatePin(saveForecastContext.getPin());
				forecastVolumeDO.setGmtModifiedPin(saveForecastContext.getPin());
				forecastVolumeDao.insert(forecastVolumeDO);
			});
			
			saveForecastContext.setForecastCode(nextSeq);
		} catch (Exception e) {
			throw TmsExceptionUtil.wrapException(e);
		}
		return true;
	}
	
	private ForecastDO buildForcast(String nextSeq,SaveForecastContext saveForecastContext,CalculateFreightContext calculateFreightContext,CalculateWeightContext calculateWeightContext){
		ForecastDO forecastDO= ForecastDO.builder()
				.companyCode(calculateFreightContext.getCompanyCode())
				.amount(calculateFreightContext.getAmount())
				.auditState(1)
				.cargoTypeCode(calculateWeightContext.getCargoTypeCode())
				.cargoTypeName(calculateWeightContext.getCargoTypeName())
				.companyCode(calculateFreightContext.getCompanyCode())
				.companyName(companyDao.selectByCode(calculateFreightContext.getCompanyCode()).getCompanyName())
				.countyCode(calculateWeightContext.getCountyCode())
				.countyName(getCountryName(calculateFreightContext.getCountyCode()))
				.customerNo(saveForecastContext.getCustomerNo())
				.forecastCode(nextSeq)
				.num(saveForecastContext.getNum())
				.remark(saveForecastContext.getRemark())
				.isPrint(0)
				.saleProductCode(calculateWeightContext.getSaleProductCode())
				.saleProductName(saleProductDao.selectByCode(calculateWeightContext.getSaleProductCode()).getSaleProductName())
				.state(0)
				.weight(calculateWeightContext.getWeight())
				.totalChargeWeight(calculateWeightContext.getTotalChargeWeight())
				.totalWeight(calculateWeightContext.getTotalWeight())
				.totalVolumeWeight(calculateWeightContext.getTotalVolumeWeight())
				.build();
		forecastDO.setIp(saveForecastContext.getIp());
		forecastDO.setGmtCreatePin(saveForecastContext.getPin());
		forecastDO.setGmtModifiedPin(saveForecastContext.getPin());
		 return forecastDO;
	}
	private void setForecastReceiverDO(String nextSeq,ForecastReceiverDO  forecastReceiverDO,SaveForecastContext saveForecastContext,CalculateFreightContext calculateFreightContext,CalculateWeightContext calculateWeightContext){
		BeanUtils.copyProperties(saveForecastContext.getSaveForecastReceiverContext(), forecastReceiverDO);
		String receiverSeq = TmsSerializeConstant.FORCAST_RECEIVER_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.FORCAST_RECEIVER_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
		forecastReceiverDO.setForecastCode(nextSeq);
		forecastReceiverDO.setForecastReceiverCode(receiverSeq);
		forecastReceiverDO.setProvince(getProvinceName(saveForecastContext.getSaveForecastReceiverContext().getProvinceCode(),calculateWeightContext.getCountyCode()));
		forecastReceiverDO.setCompanyCode(calculateFreightContext.getCompanyCode());
		forecastReceiverDO.setIp(saveForecastContext.getIp());
		forecastReceiverDO.setGmtCreatePin(saveForecastContext.getPin());
		forecastReceiverDO.setGmtModifiedPin(saveForecastContext.getPin());
		if(saveForecastContext.getSaveForecastReceiverContext().getPlatformDictId()>0){
			ApiResult<DictionaryResponse> dictionaryBy = dictionaryRpcService.getDictionaryBy(saveForecastContext.getSaveForecastReceiverContext().getPlatformDictId());
			if( CommonEnum.REQUEST_SUCCESS.getCode()!=dictionaryBy.getCode()){
				throw new TmsManagerException(TmsExceptionEnum.CARGO_TYPE_DIC_IS_NOT_EXIST.getCode(), TmsExceptionEnum.CARGO_TYPE_DIC_IS_NOT_EXIST.getMessage());
			}
			if(!dictionaryBy.getData().getTypeCode().equals(PLATFORM_DIC_TYPE_CODE)){
				throw new TmsManagerException(TmsExceptionEnum.CARGO_TYPE_DIC_IS_NOT_EXIST.getCode(), TmsExceptionEnum.CARGO_TYPE_DIC_IS_NOT_EXIST.getMessage());
			}
			forecastReceiverDO.setPlatformCode(dictionaryBy.getData().getValue());
			forecastReceiverDO.setPlatformName(dictionaryBy.getData().getValueName());
		}
	}
	
	@SuppressWarnings("unused")
	private void setForecastSenderDO(String nextSeq,ForecastSenderDO forecastSenderDO,SaveForecastContext saveForecastContext,CalculateFreightContext calculateFreightContext){
		BeanUtils.copyProperties(saveForecastContext.getSaveForecastSenderContext(), forecastSenderDO);
		String senderSeq = TmsSerializeConstant.FORCAST_SENDER_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.FORCAST_SENDER_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
		forecastSenderDO.setForecastCode(nextSeq);
		forecastSenderDO.setForecastSenderCode(senderSeq);
		forecastSenderDO.setCompanyCode(calculateFreightContext.getCompanyCode());
		forecastSenderDO.setSenderCountyName(getCountryName(saveForecastContext.getSaveForecastSenderContext().getSenderCountyCode()));
		forecastSenderDO.setIp(saveForecastContext.getIp());
		forecastSenderDO.setGmtCreatePin(saveForecastContext.getPin());
		forecastSenderDO.setGmtModifiedPin(saveForecastContext.getPin());
		
		

	}
	
	private void setForecastDeclareDO(String nextSeq,ForecastDeclareDO forecastDeclareDO,SaveForecastDeclareContext saveForecastDeclareContext,CalculateFreightContext calculateFreightContext ){
		BeanUtils.copyProperties(saveForecastDeclareContext, forecastDeclareDO);
		String declareSeq = TmsSerializeConstant.FORCAST_DECLARE_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.FORCAST_DECLARE_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
		forecastDeclareDO.setForecastCode(nextSeq);
		forecastDeclareDO.setForecastDeclareCode(declareSeq);
		forecastDeclareDO.setCompanyCode(calculateFreightContext.getCompanyCode());
	}
	
	private void setForecastVolumeDO(String nextSeq,ForecastVolumeDO forecastVolumeDO,CalculateWeightVolumeContext calculateWeightVolumeContext,CalculateFreightContext calculateFreightContext){
		BeanUtils.copyProperties(calculateWeightVolumeContext, forecastVolumeDO);
		String volumeSeq = TmsSerializeConstant.FORCAST_VOLUME_KEY+globalIdGeneratorUtil.getNextSeq(TmsSerializeConstant.FORCAST_VOLUME_SEQ_KEY, TmsSerializeConstant.SEQ_INCRBY);
		forecastVolumeDO.setCompanyCode(calculateFreightContext.getCompanyCode());
		forecastVolumeDO.setForecastCode(nextSeq);
		forecastVolumeDO.setVolumeCode(volumeSeq);
	}
	
	private String getCountryName(String countryCode){
		ApiResult<CountryResponse> country = countryRpcService.getCountry(countryCode);
		if(CommonEnum.REQUEST_SUCCESS.getCode()!= country.getCode()){
			throw new TmsManagerException(TmsExceptionEnum.COUNTRY_IS_NOT_EXIST.getCode(), TmsExceptionEnum.COUNTRY_IS_NOT_EXIST.getMessage());
		}
		return country.getData().getCountryNameCn();
	}
	private String getProvinceName(String provinceCode,String countryCode){
		ApiResult<CityResponse> city = countryRpcService.getProvince(provinceCode,countryCode);
		if(CommonEnum.REQUEST_SUCCESS.getCode()!= city.getCode()){
			throw new TmsManagerException(TmsExceptionEnum.PROVINCE_IS_NOT_EXIST.getCode(), TmsExceptionEnum.PROVINCE_IS_NOT_EXIST.getMessage());
		}
		return city.getData().getCityName();
	}
	private void validateCustomNo(SaveForecastContext saveForecastContext,CalculateFreightContext calculateFreightContext){
		ForecastQuery forecastQuery = new ForecastQuery(); 
		forecastQuery.setCustomerNo(saveForecastContext.getCustomerNo());
		forecastQuery.setCompanyCode(calculateFreightContext.getCompanyCode());
		int i=forecastDao.countForecast(forecastQuery);	
		if(i>0){
			throw new TmsManagerException(TmsExceptionEnum.CUSTOMNO_IS_EXIS.getCode(), TmsExceptionEnum.CUSTOMNO_IS_EXIS.getMessage());
		}
	}

}
